﻿///////////////////////////////////////////////////////////////////////////////
// File:        Thread.cc
// Author:      671643387@qq.com
// Date:        2016年1月5日 下午5:42:07
// Description:
///////////////////////////////////////////////////////////////////////////////

#include <cassert>
#if defined(__LINUX__)
#include <unistd.h>
#endif
#include "Thread.hpp"

namespace fog
{
    namespace thread
    {
        Thread::Thread(void)
            : id_(0)
            , state_(Thread::kNotReady)
#if defined(__WINDOWS__)
            , handle_(-1L)
#elif defined(__LINUX__)
#endif
        {

        }

        Thread::~Thread(void)
        {
#if defined(__WINDOWS__)
            if (handle_ != -1L)
                ::CloseHandle(HANDLE(handle_));
#endif
        }

        bool Thread::start(void)
        {
            assert(state_ == Thread::kNotReady);
            bool fOk = false;
#if defined(__WINDOWS__)
            handle_ = ::_beginthreadex(NULL, 0, Thread::proc_,
                this, 0, (unsigned int*)&id_);
            fOk = (handle_ != -1L);
#elif defined(__LINUX__)
            fOk = (::pthread_create(&id_, NULL, Thread::proc_,
                this) == 0);
#endif
            if (fOk) state_ = Thread::kReady;
            return fOk;
        }

        void Thread::join(void)
        {
#if defined(__WINDOWS__)
            assert(handle_ != -1L);
            ::WaitForSingleObject(HANDLE(handle_), INFINITE);
            ::CloseHandle(HANDLE(handle_));
            handle_ = -1L;
#elif defined(__LINUX__)
            ::pthread_join(id_, NULL);
#endif
        }

        Thread::TID_t Thread::this_id(void)
        {
#if defined(__WINDOWS__)
            return ::GetCurrentThreadId();
#elif defined(__LINUX__)
            return ::pthread_self();
#endif
        }

        void Thread::sleep(time_t msec)
        {
#if defined(__WINDOWS__)
            ::Sleep(DWORD(msec));
#elif defined(__LINUX__)
            ::usleep(int(msec * 1000));
#endif
        }

#if defined(__WINDOWS__)
        unsigned int Thread::proc_(void* arg)
#elif defined(__LINUX__)
        void* Thread::proc_(void* arg)
#endif
        {
            assert(arg);
            Thread* pThread = static_cast<Thread*>(arg);
            pThread->state_ = Thread::kRunning;
            pThread->run();
            pThread->state_ = Thread::kExit;
            return 0;
        }
    }
}